#pragma once

#include "COMObject.h"

typedef struct IDispatchVtbl
{
	BEGIN_INTERFACE

		HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
		IDispatch * This,
		/* [in] */ REFIID riid,
		/* [iid_is][out] */ void **ppvObject);

		ULONG ( STDMETHODCALLTYPE *AddRef )(
			IDispatch * This);

		ULONG ( STDMETHODCALLTYPE *Release )(
			IDispatch * This);

		HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )(
			IDispatch * This,
			/* [out] */ UINT *pctinfo);

		HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )(
			IDispatch * This,
			/* [in] */ UINT iTInfo,
			/* [in] */ LCID lcid,
			/* [out] */ ITypeInfo **ppTInfo);

		HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )(
			IDispatch * This,
			/* [in] */ REFIID riid,
			/* [size_is][in] */ LPOLESTR *rgszNames,
			/* [in] */ UINT cNames,
			/* [in] */ LCID lcid,
			/* [size_is][out] */ DISPID *rgDispId);

		/* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )(
			IDispatch * This,
			/* [in] */ DISPID dispIdMember,
			/* [in] */ REFIID riid,
			/* [in] */ LCID lcid,
			/* [in] */ WORD wFlags,
			/* [out][in] */ DISPPARAMS *pDispParams,
			/* [out] */ VARIANT *pVarResult,
			/* [out] */ EXCEPINFO *pExcepInfo,
			/* [out] */ UINT *puArgErr);

	END_INTERFACE
} IDispatchVtbl;

class CComDispatch: public CComObject<IDispatch,IDispatchVtbl> /*, public IDispatch*/
{
public:
	CComDispatch(CJoinPoint& joinPoint):CComObject(joinPoint)
	{
		AddRef();
	}
	~CComDispatch()
	{
		Release();
	}

private:
	ULONG STDMETHODCALLTYPE AddRef()
	{
		return pDispatchVtbl->AddRef(pDispatch);
	}

	ULONG STDMETHODCALLTYPE Release()
	{
		return pDispatchVtbl->Release(pDispatch);
	}

public:
	HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo)
	{
		return pDispatchVtbl->GetTypeInfoCount(pDispatch,pctinfo);
	}

	HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo)
	{
		return pDispatchVtbl->GetTypeInfo(pDispatch,iTInfo,lcid,ppTInfo);
	}

	HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId)
	{
		return pDispatchVtbl->GetIDsOfNames(pDispatch,riid,rgszNames,cNames,lcid,rgDispId);
	}

	HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
	{
		return pDispatchVtbl->Invoke(pDispatch,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);
	}
};

